<template>
	<div class="content">
		<text>当前绑定的设备编号</text>
		<input class="memberItIn" v-model="name" />
		<view class="btMain">
			<button class="btOne" @click="getText()">粘贴微信拷贝编号</button>
			<button class="btOne" @click="setStorageSyncName">更新绑定设备编号</button>
		</view>
		<view class="btMain">
			<button class="btOne" @click="testReconnect">手动连接蓝牙设备</button>
			<button class="btOne" @click="clearLogs">清空日志</button>
		</view>
		<view class="log-list" v-if="0">
			<div>搜索到的蓝牙设备列表</div>
			<div class="log-item blue-item" :class="[item.name!=formData.code?'select':'']" v-for="(item,index) in 0"
				:key="index">
				<span>{{index}}-{{item.name}}-{{item.deviceId}}</span>
			</div>
		</view>
		<view class="btMain">
			<button class="btOne open" @click="openDoor(1)">开门1</button>
			<button class="btOne open" @click="openDoor(2)">开门2</button>
			<button class="btOne open" @click="openDoor(3)">开门3</button>
			<button class="btOne open" @click="openDoor(4)">开门4</button>
			<button class="btOne open" @click="testChange" v-if="0">test</button>

		</view>
		<view class="log-list">
			<div>日志区</div>
			<div class="log-item" v-for="(item,index) in logs" :key="index">
				<span>{{item}}</span>
			</div>
		</view>
	</div>
</template>

<script>
	import config from '../../static/config.js'
	import util from '../../static/utils/util.js'
	var delayTimer; //用来控制是否持续服务发现
	export default {
		data() {
			return {
				images: config.images,
				localImages: config.localImages,
				formData: {
					code: "18874183954",
					"roomIdNow": "22918",
					"openId": "onZpA5JuIaDlrDdaANOGGUcdo-g0",
					"roomId": "",
				},
				logs: getApp().globalData.logs || [],
				service: "0783b03e-8535-b5a0-7140-a304f013c3b7",
				delayTimer: null,
				deviceId: '',
				serviceId: '',
				charId: '',
				name: wx.getStorageSync("name") || "00002122868A",
				test:false,
			}
		},
		watch: {
			test: {
				handler(newVal, oldVal) {
					console.log('count',newVal,oldVal)
				},
				immediate: true,
			},
		},
		onLoad() {
			this.test=getApp().globalData.test
		},
		onShow() {
			console.log('getApp().globalData', getApp().globalData)
			this.initBLEApp()
		},

		onUnload() {
			this.clearLogs()
		},

		methods: {
			testChange(){
				getApp().toggleTest()
			},

			async openDoor(door) {
				var openDoorFlag=await getApp().testOpenDoor(door)
				if(openDoorFlag){
					console.log('openDoorFlag',openDoorFlag)
				}
			},

			async initBLEApp() {
				var res=await getApp().initBLE()
				console.log('res',res)				
			},
			testReconnect() {
				getApp().testReconnect()
			},

			clearLogs() {
				//清空日志
				getApp().globalData.logs = []
				this.logs = getApp().globalData.logs
			},

			setStorageSyncName() {
				console.log('this.name',this.name)
				wx.setStorageSync("name", this.name)
				getApp().globalData.battery=0
				getApp().globalData.deviceId=""
				getApp().globalData.isConnect=false
				getApp().globalData.name=this.name
				util.toast('更新设备成功')
			},

			onShowModal() {
				var that = this;
				wx.showModal({
					title: '用户提示',
					content: '请先打开手机蓝牙',
					cancelColor: "#999999",
					confirmColor: "#1086FF",
					confirmText: '已打开',
					cancelText: '取消',
					success(res) {
						if (res.confirm) {
							that.initBLE()
						} else if (res.cancel) {}
					}
				})
			},

			//请点击设置按钮打开
			wxgetSetting() {
				var that = this;
				//（1）获取用户授权的信息
				wx.getSetting({
					success(res) {
						console.log('getSetting', res);
						//判断scope.writePhotosAlbum的值，若为true则已经授权
						if (res.authSetting['scope.bluetooth']) {
							that.initBLE();
							//若为undefined，则说明是第一次授权，需要调用wx.authorize弹出授权框，授权框只在第一次询问时弹出，如果用户已经拒绝了，则不会弹出。
						} else if (res.authSetting['scope.bluetooth'] === undefined) {
							wx.authorize({
								scope: 'scope.bluetooth',
								success() {
									that.initBLE();
								},
								fail(res) {
									console.log('authorize-fail', res);
								}
							})
						} else {
							//若为false,则已经拒绝了授权，这时候我们需要调用wx.openSetting引导用户打开设置，保存到相册
							//wx.openSetting,打开小程序设置页,避免此类滥用情况，微信调整了开启方式，button和对话框Modad确认按钮调用wx.openSetting有效
							that.openBlueModel()
						}
					}
				})
			},

			openBlueModel() {
				var that = this;
				wx.showModal({
					title: "温馨提示",
					content: '您没有开启蓝牙授权开关，请点击设置按钮打开',
					confirmText: '去设置',
					confirmColor: "#1086FF",
					cancelText: '取消',
					success(res) {
						if (res.confirm) {
							wx.openSetting({
								success(res) {
									if (res.authSetting['scope.bluetooth']) {
										//连接蓝牙
										that.initBLE();
									} else {
										wx.showToast({
											title: '您没有开启蓝牙授权开关',
											icon: 'none'
										})
									}
								},
							})
						}
					},
				})
			},

			initBLE() {
				var that = this;
				this.printLog("启动蓝牙适配器, 蓝牙初始化")
				wx.openBluetoothAdapter({
					success(res) {
						console.log('openBluetoothAdapter', res);
						that.findBLE();
					},
					fail(res) {
						console.log("请先打开蓝牙", res);
						that.printLog("请先打开蓝牙" + JSON.stringify(res))
						if (res.errCode == 10001) {
							that.onShowModal();
						}
					}
				})
			},

			printLog(msg) {
				this.logs.push(msg);
			},

			findBLE() {
				var that = this;
				//只搜索主服务 UUID 为 service 的设备
				wx.startBluetoothDevicesDiscovery({
					// services: [this.service],
					success(res) {
						console.log("正在搜索设备", res);
						that.printLog("正在搜索设备")
						that.delayTimer = setInterval(function() {
							that.discoveryBLE() //这里的discovery需要多次调用
							// console.log('delayTimer', that.delayTimer)
						}, 1000);
						setTimeout(function() {
							that.closeSearch()
						}, 6000);
					}
				})
			},

			discoveryBLE() {
				var that = this
				wx.getBluetoothDevices({
					success(res) {
						var list = res.devices;
						console.log(list);
						if (list.length <= 0) {
							return;
						}
						var devices = [];
						for (var i = 0; i < list.length; i++) {
							var name = list[i].name || list[i].localName;
							// 名字为空就跳出循环
							if (util.isEmpty(name)) {
								continue;
							}
							// 连接的蓝牙设备地址deviceId对于mac地址 "A8:5A:E0:5A:CD:17"
							var deviceId = list[i].deviceId
							var nameFind = "00002122868A"; // 连接的蓝牙设备名称
							var nameFind = that.name; // 连接的蓝牙设备名称
							if (name == nameFind) {
								console.log("找到指定设备", name, list[i]);
								that.printLog("找到指定设备" + name);
								that.closeSearch()
								that.deviceId = deviceId
								that.createBlueDirect(deviceId, name);
								break;
							}
						}
					},
					fail() {
						util.toastError('搜索蓝牙设备失败');
					}
				})
			},
			closeSearch() {
				var that = this
				if (that.delayTimer) {
					clearInterval(that.delayTimer);
					that.delayTimer = null
					wx.stopBluetoothDevicesDiscovery({
						success(res) {
							that.printLog('连接蓝牙成功之后关闭蓝牙搜索');
						}
					})
				}
			},

			testConnect() {
				this.closeBLE(this.deviceId, () => {
					console.log("预先关闭之前的连接，再打开新的蓝牙连接");
					setTimeout(() => {
						this.createBlueDirect(this.deviceId, this.name)
					}, 500)
				})
			},

			closeBLE(deviceId, callback) {
				var that = this;
				wx.closeBLEConnection({
					deviceId: deviceId,
					success(res) {
						that.printLog("断开设备[" + deviceId + "]成功.");
						console.log(res)
					},
					fail(res) {
						that.printLog("断开设备成功.");
					},
					complete: callback
				})
			},

			createBlueDirect(deviceId, name) {
				var that = this;
				this.printLog("连接: [" + name + '-' + deviceId + "]");
				console.log("连接: [" + name + '-' + deviceId + "]");
				wx.createBLEConnection({
					deviceId: deviceId,
					async success(res) {
						that.printLog("设备连接成功");
						console.log("设备连接成功");
						var serviceId = await that.getBLEServiceId(deviceId)
						var charId = await that.getBLECharactedId(deviceId, serviceId);
						that.sendBLECharacterNotice(deviceId, serviceId, charId);
						// writeBLE(deviceId, serviceId, charId, buffer)
					},
					fail(res) {
						that.printLog("设备连接失败", res);
						console.log("设备连接失败", res);
					}
				})
			},

			//获取服务UUID
			getBLEServiceId(deviceId) {
				this.printLog("获取设备[" + deviceId + "]服务列表")
				var that = this;
				return new Promise((resolve, reject) => {
					wx.getBLEDeviceServices({
						deviceId: deviceId,
						success(res) {
							var services = res.services;
							console.log('services', services);
							if (services.length <= 0) {
								that.printLog("未找到主服务列表")
								return;
							}
							that.printLog('找到设备服务列表个数: ' + services.length);
							if (services.length) {
								var service = services[0];
								var serviceId = service.uuid
								that.serviceId = serviceId
								console.log("服务UUID:[" + serviceId + "] Primary:" + service.isPrimary);
								that.printLog("服务UUID:[" + serviceId + "] Primary:" + service
									.isPrimary);
								// that.getBLECharactedId(deviceId, serviceId);
								resolve(serviceId)
							}
						},
						fail(res) {
							that.printLog("获取设备服务列表失败" + res.errMsg);
						}
					})
				})
			},

			getBLECharactedId(deviceId, serviceId) {
				this.printLog("获取设备特征值")
				var that = this;
				return new Promise((resolve, reject) => {

					wx.getBLEDeviceCharacteristics({
						deviceId: deviceId,
						serviceId: serviceId,
						success(res) {
							console.log(res);
							//这里会获取到两个特征值，一个用来写，一个用来读
							var chars = res.characteristics;
							if (chars.length <= 0) {
								that.printLog("未找到设备特征值")
								return;
							}
							that.printLog("找到设备特征值个数:" + chars.length);
							if (chars.length == 2) {
								for (var i = 0; i < chars.length; i++) {
									var char = chars[i];
									that.printLog("特征值[" + char.uuid + "]")
									var prop = char.properties;
									if (prop.notify) {
										that.printLog("该特征值属性: Notify");
										that.recvBLECharacterNotice(deviceId, serviceId, char.uuid);
									} else if (prop.write) {
										that.printLog("该特征值属性: Write");
										// that.sendBLECharacterNotice(deviceId, serviceId, char.uuid);
										resolve(char.uuid)
									} else {
										that.printLog("该特征值属性: 其他");
									}
								}
							}
						},
						fail(res) {
							that.printLog("获取设备特征值失败")
						}
					})

				})
			},

			recvBLECharacterNotice(deviceId, serviceId, charId) {
				//接收设置是否成功
				this.printLog("注册Notice 回调函数");
				var that = this;
				wx.notifyBLECharacteristicValueChange({
					deviceId: deviceId,
					serviceId: serviceId,
					characteristicId: charId,
					state: true, //启用Notify功能
					success(res) {
						wx.onBLECharacteristicValueChange(function(res) {
							var strCode = that.ab2hex(res.value)
							console.log("收到Notify数据: " + strCode);
							that.printLog("收到Notify数据: " + strCode);
							if (strCode.match(/011\d{1}/)) {
								console.log('battrey', strCode.exec(/011(\d{1})/)[1])
								//发起开门指令-writeBLECharacteristicValue:fail:property not support
								// that.openCode(deviceId, serviceId, charId)
							}
							// 返回的值ff550e023200002122868a01158f
							//0115 0x01:电机到位 0x15电池电量5格
						});
					},
					fail(res) {
						console.log(res);
						that.printLog("特征值Notice 接收数据失败: " + res.errMsg);
					}
				})
			},


			//连接握手指令拼接
			connectCode(str = "00002122868A") {
				var arr1 = [0xFF, 0x55, 0x12, 0x01, 0x05]
				//00002122868A转换成[0x00, 0x00, 0x21, 0x22, 0x86, 0x8A]
				var arr2 = str.match(/[\da-f]{2}/gi).map((item) => parseInt(item, 16))
				var arr3 = [0x01, 0x6C, 0x6F, 0x67, 0x69, 0x6E]
				var arr = [].concat(arr1, arr2, arr3)
				//对上面的数组每个值进行异或运算得到异或校验值
				var hex = arr.reduce((pre, cur) => pre ^ cur)
				//添加到数组末端
				arr.push(hex)
				return arr
			},

			//发送wifi信息中的名称和密码ssid/pass，信息转换成stringbuffer二进制类型，发送给蓝牙设备
			sendBLECharacterNotice(deviceId, serviceId, charId) {
				var that = this;
				// var buffer = this.string2buffer(string);
				// this.printLog("延时1秒后，发送开门");

				// 设备编号: 00002122868A
				// var string="0xFF 55 12 01 05 00 00 21 22 86 8A 01 6C 6F 67 69 6E D1"
				// 连接握手 ，最后一位异或的值：D1
				var arr = [0xFF, 0x55, 0x12, 0x01, 0x05, 0x00, 0x00, 0x21, 0x22, 0x86, 0x8A, 0x01, 0x6C, 0x6F,
					0x67,
					0x69, 0x6E, 0xD1
				]
				var buffer = that.getBuffer(arr)
				this.writeBLE(deviceId, serviceId, charId, buffer)
				// 返回的值ff550e023200002122868a01158f
				//0115 0x01:电机到位 0x15电池电量5格

				// that.openCode(deviceId, serviceId, charId)

				//发完连接握手指令，收到握手回应，然后要间隔多久可以接着发开门指令
				//现在直接发开门指令，暂时没收到消息回应。发完握手指令，接着发开门指令也没收到回应
				setTimeout(function() {
					that.openCode(deviceId, serviceId, charId)
				}, 1000);
			},

			//开锁指令
			openCode(deviceId, serviceId, charId) {
				var string = "0xFF 55 12 01 05 00 00 21 22 86 8A 02 00 00 04 00 00 B5"
				// 开锁 No4
				var arr1 = [0xFF, 0x55, 0x12, 0x01, 0x05, 0x00, 0x00, 0x21, 0x22, 0x86, 0x8A, 0x02, 0x00,
					0x00, 0x04,
					0x00, 0x00, 0xB5
				]
				var buffer1 = this.getBuffer(arr1)
				this.writeBLE(deviceId, serviceId, charId, buffer1)
			},


			getBuffer(arr) {
				var buffer = new ArrayBuffer(arr.length)
				var dataView = new DataView(buffer)
				for (var i = 0; i < arr.length; i++) {
					dataView.setUint8(i, arr[i])
				}
				return buffer
			},

			writeBLE(deviceId, serviceId, charId, buffer) {
				var that = this
				console.log("发送指令=" + that.ab2hex(buffer));
				wx.writeBLECharacteristicValue({
					deviceId: deviceId,
					serviceId: serviceId,
					characteristicId: charId,
					value: buffer,
					success(res) {
						that.printLog("发送指令成功" + that.ab2hex(buffer));
						console.log("发送指令成功" + that.ab2hex(buffer));
					},
					fail(res) {
						console.log(res);
						that.printLog("发送失败." + res.errMsg);
					},
					complete() {

					}
				})
			},

			// 将字符串转换成ArrayBufer
			string2buffer(str) {
				if (!str) return;
				var val = "";
				for (var i = 0; i < str.length; i++) {
					val += str.charCodeAt(i).toString(16);
				}
				console.log(val);
				str = val;
				val = "";
				let length = str.length;
				let index = 0;
				let array = []
				while (index < length) {
					array.push(str.substring(index, index + 2));
					index = index + 2;
				}
				val = array.join(",");
				// 将16进制转化为ArrayBuffer
				return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function(h) {
					return parseInt(h, 16)
				})).buffer
			},

			/**
			 * 将ArrayBuffer转换成字符串
			 */
			ab2hex(buffer) {
				var hexArr = Array.prototype.map.call(
					new Uint8Array(buffer),
					function(bit) {
						return ('00' + bit.toString(16)).slice(-2)
					}
				)
				return hexArr.join('');
			},

			getText() {
				var self = this;
				wx.getClipboardData({
					success(res) {
						console.warn(res.data) // data
						self.formData.code = res.data;
					}
				})
			},
			returnMain(type = 0) {
				var phoneNumber = this.formData.code;
				wx.setStorageSync('phone', phoneNumber);
				// 开启测试模式
				getApp().globalData.test = true
				wx.navigateTo({
					url: '/pages/index/select'
				})
			},

		},

	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		text-align: center;
		/* justify-content: center; */
	}

	.memberItIn {
		width: 500rpx;
		border: 1rpx solid;
	}

	.btMain {
		display: flex;
		flex-direction: row;
		margin-top: 10rpx;
	}

	.btOne {
		/* width: 300rpx; */
		margin: 10rpx;
	}

	.btOne.open {
		width: 23%
	}

	.log-list {
		display: flex;
		flex-direction: column;
		justify-content: left;
		width: 100vw;
		padding: 20rpx;
		border: 1rpx solid #ccc;
	}

	.log-item {
		margin: 4rpx;
		text-align: left;
		/* border: 1rpx solid #ccc; */
	}

	.blue-item {
		padding: 10rpx;
		border: 1rpx solid #ccc;
	}

	.blue-item.select {
		border: 2rpx solid #00f;
	}
</style>
